css 面试总结
2023-07-20 22:59:45 # fontend

1. 盒模型

css 中所有的元素都是被一个个 “盒子” 包围着,盒模型定义了盒子的组成部分 margin padding border and content, 合在一起就可以创建我们在页面上看到的内容。盒模型有两种:标准盒模型和替代(IE)盒模型。
标准盒模型: 设置的 width ,height 实际设置的是 content-box,和 padding,border 一起组成盒子的大小。
替代(IE)盒模型:设置的 width, height 表示的是盒子的大小,也就是包括 padding border的大小

1
2
3
.box {
box-sizing: border-box; // ie 盒模型
}

2. 格式上下文

BFC (block formatting context)

定义:

块级格式化上下文,是一个独立的渲染区域,规定了内部如何布局,BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。所以当 BFC 外部存在浮动时,它不应该影响 BFC 内部 Box 的布局,BFC 会通过变窄,而不与浮动有重叠。 同样的,当 BFC 内部有浮动时,为了不影响外部元素的布局,BFC 计算高度时会包括浮动的高度。

怎样生成 BFC:

  1. 根元素
  2. float 的值不为 none
  3. position 的属性为 absolute 或者 fixed sticky
  4. display 的属性为 inline-block table-cell table-caption
  5. overflow 的属性不为 visible
  6. flex items

在布局中的应用:

  1. 清除浮动: 浮动元素会脱离正常文档流,它会浮动到最近的块级元素的边界处,并且计算 bfc 高度时,float 元素也参与计算,所以想让浮动元素正常显示的话,可以将其包裹在 bfc 中
  2. 防止 margin 重叠(塌陷):规定 bfc 的 box 中相邻 div 垂直方向上的 margin 只会取较大值,如果在其中一个 div 外包裹一层 bfc 则可以避免此问题,水平方向也会发生重叠
  3. 自适应多栏布局
    1. 自适应两栏布局: 子float 子bfc, 规则:bfc不会与浮动元素重叠,bfc的宽度会根据父和子float的宽度,自动变窄
    2. 自适应三栏布局: 左右float中间bfc, 规则:同上

3. 实现水平垂直居中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
// 第一种 
.parent {
position: relative;
}

.center {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}

// 第二种
.parent {
display: flex;
align-items: center;
justify-content: center;
}

// 第三种
.parent {
position: relative;
}

.center {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
}

// 第四种
.parent {
display: grid;
}
.center {
margin: auto;
}

// 第五种
.parent {
display: grid;
place-content: center;
// 在父层元素中使用 place-content 属性,将其值设置为 center,它将在水平和垂直方向上置中其子元素
}

// 第六种 文字水平垂直居中 text-align + line-height
.parent {
width: 400px;
height: 400px;
background-color: #ccc;
text-align: center;
}

.center {
line-height: 400px;
}

// 以下是固定高宽的方案
// 第一种
.parent {
position: relative;
}

.center {
position: absolute;
top: 50%;
left: 50%;
margin-left: -50px;
margin-top: -50px;
}

// 第二种
.parent {
position: relative;
}

.center {
position: absolute;
top: calc(50% - 50px);
left: calc(50% - 50px);
}

4. 实现 16:9 或者 4:3 的一个容器

提供一个容器,设置容器的高度为 0,再设置 padding-bottom 或者 padding-top 为 56.25%(因为padding的百分比是按照容器宽度计算的,所以由 padding 来撑开容器高度,而不是 height,保证了容器的宽高比例),最后设置视频绝对定位,其宽高为容器的 100%。

5. 回流(reflow) & 重绘(repaint)

reflow: 修改了元素的几何属性,大小或者位置,是否可见这种就会触发回流
repaint: 只修改元素的样式不影响它在文档流中的位置时,比如颜色,文本方向,阴影的修改,就只会触发重绘

触发回流的场景:

  1. 页面首次渲染
  2. 浏览器窗口大小改变
  3. 元素尺寸或位置发生改变
  4. 元素内容发生改变,比如文字数量或图片大小
  5. 元素字体大小变化
  6. 添加或删除可见的dom
  7. 激活 css 的伪类比如 :hover
  8. js 查询元素的某些方法或属性: clientWidth, clientHeight, getComputedStyle 等

回流比重绘的性能消耗更高,频繁触发回流容易消耗更大的性能,性能优化中的方案之一就是从减少回流的次数来避免性能消耗。

如何避免:

  1. 如果想设定元素的样式,可以通过改变元素的 class
  2. 对于复杂的动画 对其设置 position: fixed / absolute 尽可能使元素脱离文档流 减少对其他元素的影响
  3. 可以使用 css3 的动画: transform opacity filters,这些不会引起回流重绘
  4. 避免使用 css 的 js 表达式
  5. js 改变样式的时候可以先计算,后赋值,避免多次获取属性和赋值,引起重绘
  6. 动态添加 dom 节点的时候,可以先创建一个父 dom, 然后构造好子节点,一次性 append 到 document 中,避免多次添加引起回流

6. 弹性布局

flex: flex-grow flex-shrink flex-basis;
flex-grow: 容器宽度大于元素宽度的时候,元素大小如何分配剩余空间的相对比例,默认是0,如果存在剩余空间也不放大
flex-shrink:定义flex元素的收缩规则,当容器宽度有剩余的时候,此属性不生效, 默认是1
flex-basis:定义元素在主轴上的初始尺寸, 默认是 auto
flex-wrap: 是否换行
flex-direction: 定义主轴方向
Flex-flow: flex-direction, flex-wrap

7. 响应式设计

特点:适配多端显示;网站的布局会根据视口大小调整模块的大小和位置
方法:

  1. 媒体查询
  2. rem方案
  3. 百分比
  4. vw/vh

8. 如何让浏览器支持小于12px的字体

  1. zoom: 变焦,50% or 0.5, 此属性有兼容性问题, 并且会改变元素所占空间大小,触发重排
  2. transform: scale(50%),进行缩放,注意 此属性只对可以定义高宽的元素生效,行内元素不生效, 缩放不会改变元素所占空间的大小,也不会影响布局

9. 块级元素和行内元素

块级元素:

  • 独占一行,宽度默认充满父级
  • 高宽,margin,padding 都有效
  • 多个块级元素相邻时,默认从上到下排列

行内元素:

  • 相邻元素默认可依次排列
  • 宽度默认由元素宽度撑开,设置高宽无效,margin,padding 的左右方向有效,上下间距无效,
  • 设置行高有效
  • 行内元素中不能放块级元素,a标签内部不能再放a标签
  • 常见行内元素: span input textarea , 默认情况下 大多数文本 替换元素以及生成的内容都是行级的
  • 行内块级元素: img button input textarea select,可设置 width height margin padding,但是默认宽度是它们自己的宽度,相岭之间会有空白间隙,设置它的上一级 font-size 为0 可以消除间隙

10. transition 和 animation 的区别

  1. transition 是过渡元素,需要触发事件来执行, animation 的动画元素,可以自己执行,并且可以循环执行。
  2. transition 只有开始和结束状态,animation 可以自定义多个状态
  3. transition 是基于 css 属性值发生变化来实现过渡效果,支持的属性值不多,animation 比 transition 更强大些,支持更多的动画效果和更灵活的动画的流程控制

11. display:none 和 visibility: hidden 的差别

display:none: 表示元素从布局中移除,包括占用的空间
visibility: hidden: 表示隐藏元素,但是占用的空间仍会保留